import { 
  Element, 
  ElementPair, 
  ElementCombine, 
  ElementCombinePair, 
  MolecularFormula,
  EquationPosition
} from './chemistry'
import { Equation } from './equation'

// 化学方程式解析器
export class ChemicalParser {
  
  // 解析化学方程式字符串
  static parseEquation(equationStr: string): Equation | null {
    try {
      // 去除空格并分割左右两边
      const cleanStr = equationStr.replace(/\s+/g, '');
      const parts = cleanStr.split(/[=→]/);
      
      if (parts.length !== 2) {
        throw new Error('方程式格式错误，必须包含等号或箭头');
      }

      const [leftStr, rightStr] = parts;
      const equation = new Equation();

      // 解析左边
      const leftFormulas = this.parseFormulas(leftStr);
      for (const formula of leftFormulas) {
        const position = new EquationPosition(formula);
        equation.appendLeft(position);
      }

      // 解析右边
      const rightFormulas = this.parseFormulas(rightStr);
      for (const formula of rightFormulas) {
        const position = new EquationPosition(formula);
        equation.appendRight(position);
      }

      return equation;
    } catch (error) {
      console.error('解析方程式失败:', error);
      return null;
    }
  }

  // 解析分子式列表（用+号分隔）
  private static parseFormulas(formulasStr: string): MolecularFormula[] {
    const formulas: MolecularFormula[] = [];
    const formulaStrings = formulasStr.split('+');
    
    for (const formulaStr of formulaStrings) {
      if (formulaStr.trim()) {
        const formula = this.parseFormula(formulaStr.trim());
        if (formula) {
          formulas.push(formula);
        }
      }
    }
    
    return formulas;
  }

  // 解析单个分子式
  static parseFormula(formulaStr: string): MolecularFormula | null {
    try {
      const formula = new MolecularFormula();
      let i = 0;
      
      while (i < formulaStr.length) {
        const result = this.parseGroup(formulaStr, i);
        if (!result) break;
        
        formula.append(result.group);
        i = result.nextIndex;
      }
      
      return formula;
    } catch (error) {
      console.error('解析分子式失败:', error);
      return null;
    }
  }

  // 解析组（可能是单个元素或括号组合）
  private static parseGroup(str: string, startIndex: number): { group: ElementCombinePair, nextIndex: number } | null {
    let i = startIndex;
    
    if (str[i] === '(') {
      // 解析括号组合
      i++; // 跳过 '('
      const combine = new ElementCombine();
      
      while (i < str.length && str[i] !== ')') {
        const elementResult = this.parseElementPair(str, i);
        if (!elementResult) break;
        
        combine.append(elementResult.pair);
        i = elementResult.nextIndex;
      }
      
      if (i >= str.length || str[i] !== ')') {
        throw new Error('括号不匹配');
      }
      
      i++; // 跳过 ')'
      
      // 解析括号后的数字
      const countResult = this.parseNumber(str, i);
      const count = countResult.number || 1;
      i = countResult.nextIndex;
      
      return {
        group: new ElementCombinePair(combine, count),
        nextIndex: i
      };
    } else {
      // 解析单个元素
      const elementResult = this.parseElementPair(str, i);
      if (!elementResult) return null;
      
      const combine = new ElementCombine();
      combine.append(elementResult.pair);
      
      return {
        group: new ElementCombinePair(combine, 1),
        nextIndex: elementResult.nextIndex
      };
    }
  }

  // 解析元素对（如 H2, Ca, O）
  private static parseElementPair(str: string, startIndex: number): { pair: ElementPair, nextIndex: number } | null {
    let i = startIndex;
    
    // 解析元素名称（首字母大写，可能跟小写字母）
    if (i >= str.length || !/[A-Z]/.test(str[i])) {
      return null;
    }
    
    let elementName = str[i++];
    
    // 添加小写字母
    while (i < str.length && /[a-z]/.test(str[i])) {
      elementName += str[i++];
    }
    
    // 解析数字
    const countResult = this.parseNumber(str, i);
    const count = countResult.number || 1;
    i = countResult.nextIndex;
    
    const element = new Element(elementName);
    const pair = new ElementPair(element, count);
    
    return {
      pair,
      nextIndex: i
    };
  }

  // 解析数字
  private static parseNumber(str: string, startIndex: number): { number: number | null, nextIndex: number } {
    let i = startIndex;
    let numStr = '';
    
    while (i < str.length && /[0-9]/.test(str[i])) {
      numStr += str[i++];
    }
    
    return {
      number: numStr ? parseInt(numStr, 10) : null,
      nextIndex: i
    };
  }
}

// 常用分子式构建器
export class FormulaBuilder {
  // 构建常见分子式
  static buildWater(): MolecularFormula {
    return this.buildH2O();
  }

  static buildH2O(): MolecularFormula {
    const formula = new MolecularFormula();
    
    // H2
    const h = new Element('H');
    const h2 = new ElementPair(h, 2);
    const hCombine = new ElementCombine();
    hCombine.append(h2);
    const hCombinePair = new ElementCombinePair(hCombine, 1);
    
    // O
    const o = new Element('O');
    const o1 = new ElementPair(o, 1);
    const oCombine = new ElementCombine();
    oCombine.append(o1);
    const oCombinePair = new ElementCombinePair(oCombine, 1);
    
    formula.append(hCombinePair);
    formula.append(oCombinePair);
    
    return formula;
  }

  static buildH2SO4(): MolecularFormula {
    const formula = new MolecularFormula();
    
    // H2
    const h = new Element('H');
    const h2 = new ElementPair(h, 2);
    const hCombine = new ElementCombine();
    hCombine.append(h2);
    const hCombinePair = new ElementCombinePair(hCombine, 1);
    
    // SO4
    const s = new Element('S');
    const o = new Element('O');
    const s1 = new ElementPair(s, 1);
    const o4 = new ElementPair(o, 4);
    const so4Combine = new ElementCombine();
    so4Combine.append(s1);
    so4Combine.append(o4);
    const so4CombinePair = new ElementCombinePair(so4Combine, 1);
    
    formula.append(hCombinePair);
    formula.append(so4CombinePair);
    
    return formula;
  }

  // 从字符串快速构建
  static fromString(formulaStr: string): MolecularFormula | null {
    return ChemicalParser.parseFormula(formulaStr);
  }
}